
import React, { useState } from "react";
import { Switch, Input, Select, Button } from "antd";
import "./index.less";
import { Props } from "./interface";
import If from "./If";
import { OptionsValidate } from "./validate";
import {
    ArrowUpOutlined,
    ArrowDownOutlined,
    DeleteOutlined,
} from "@ant-design/icons";

let draging: any = null;
let targetName = "config-item-option"; //需要换位目标
let targetIndex = -1; //当前换位位置
let prevIndex = -1; //原坐标
const Option = Select.Option;
const Config = (props: Props) => {
    const { active, formList, setList, setActive } = props;
    // fn 拖动开始
    function dragStartFn(index, e) {
        e.dataTransfer.setData("te", e.target.innerText); //不能使用text，firefox会打开新tab
        draging = e.target;
        prevIndex = index;
    }
    // fn 拖动中
    function dragOverFn(index, e) {
        e.preventDefault();
        let target = getParentNode(e.target);
        if (!target || target.className !== targetName) return;
        if (target !== draging && draging) {
            //getBoundingClientRect()用于获取某个元素相对于视窗的位置集合
            let targetRect = target.getBoundingClientRect();
            let dragingRect = draging.getBoundingClientRect();
            if (target && target.animated) return;
            //  prevIndex = dragIndex(draging);
            // targetIndex = dragIndex(target);
            targetIndex = index;
            // if (prevIndex < targetIndex) {
            //     //nextSibling 属性可返回某个元素之后紧跟的节点（处于同一树层级中）。
            //     target.parentNode.insertBefore(draging, target.nextSibling);
            // } else {
            //     target.parentNode.insertBefore(draging, target);
            // }
            // dragAnimate(dragingRect, draging);
            //  dragAnimate(targetRect, target);
        }
    }
    // fn 拖动结束
    function dragEndFn() {
        let newList = [...formList];
        let param: any = newList[active].options;
        let prev = param[prevIndex];
        let target = param[targetIndex];
        param.splice(prevIndex, 1, target);
        param.splice(targetIndex, 1, prev);
        newList[active].options = [...param];
        setList([...newList]);
    }
    // 阶梯查询父级元素
    function getParentNode(el) {
        if (el.className === "") return getParentNode(el.parentNode);
        if (el.className === targetName) return el;
        let parentName = el.parentNode.className;
        if (parentName !== targetName) return getParentNode(el.parentNode);
        if (parentName === targetName) return el.parentNode;
    }
    //获取元素在父元素中的index
    function dragIndex(el) {
        let index = 0;
        if (!el || !el.parentNode) return -1;
        //previousElementSibling属性返回指定元素的前一个兄弟元素（相同节点树层中的前一个元素节点）。
        while (el && (el = el.previousElementSibling)) {
            index++;
        }
        return index;
    }
    function dragAnimate(prevRect, target) {
        let ms = 300;
        let currentRect = target.getBoundingClientRect();
        //nodeType 属性返回以数字值返回指定节点的节点类型。1=元素节点  2=属性节点
        if (prevRect.nodeType === 1) {
            prevRect = prevRect.getBoundingClientRect();
        }
        dragStyle(target, "transition", "none");
        dragStyle(
            target,
            "transform",
            "translate3d(" +
                (prevRect.left - currentRect.left) +
                "px," +
                (prevRect.top - currentRect.top) +
                "px,0)"
        );

        target.offsetWidth; // 触发重绘
        dragStyle(target, "transition", "all " + ms + "ms");
        dragStyle(target, "transform", "translate3d(0,0,0)");

        clearTimeout(target.animated);
        target.animated = setTimeout(() => {
            dragStyle(target, "transition", "");
            dragStyle(target, "transform", "");
            target.animated = false;
        }, ms);
    }
    //给元素添加style
    function dragStyle(el, prop, val) {
        let style = el && el.style;
        if (!style) return false;
        if (val === void 0) {
            //使用DefaultView属性可以指定打开窗体时所用的视图
            if (document.defaultView && document.defaultView.getComputedStyle) {
                val = document.defaultView.getComputedStyle(el, "");
            } else if (el.currentStyle) {
                val = el.currentStyle;
            }

            return prop === void 0 ? val : val[prop];
        } else {
            if (!(prop in style)) prop = "-webkit-" + prop;
            style[prop] = val + (typeof val === "string" ? "" : "px");
        }
    }
    // 表单传值
    function changeValue(name: string, e) {
        let param = e && e.target ? e.target.value : e;
        let arr = [...formList];
        arr[active][name] = param;
        setList(arr);
    }
    // 表单传值-option
    function changeOptionValue(index: number, e) {
        let value = e && e.target ? e.target.value : e;
        let arr = [...formList];
        let param: any = arr[active].options;
        param[index].label = value;
        setList(arr);
    }
    // fn 删除控件
    function delItemFn() {
        let newList = [...formList];
        newList.splice(active, 1);
        setList(newList);
        setActive(-1);
    }
    // fn option 新增
    function addOptionFn() {
        let index = formList[active]?.options?.length || 0;
        let param = {
            label: `选项${index}`,
            value: index,
        };
        let newList = [...formList];
        let options: any = newList[active].options;
        newList[active].options = [...options, param];
        setList(newList);
    }
    // fn 删除 options
    function delOptionFn(index) {
        let newList = [...formList];
        newList[active]?.options?.splice(index, 1);
        setList(newList);
    }
    // fn 排序 options
    function orderOptionFn(index: number, desc: boolean, disabled: boolean) {
        if (disabled) return; //排除无法换位的情况
        let newList = [...formList];
        let param = newList[active]?.options;
        let prev: any = param ? param[index] : "";
        let newIndex;
        switch (desc) {
            case true:
                newIndex = param ? param[index + 1] : "";
                newList[active]?.options?.splice(index + 1, 1, prev);
                break;

            default:
                newIndex = param ? param[index - 1] : "";
                newList[active]?.options?.splice(index - 1, 1, prev);
        }
        newList[active]?.options?.splice(index, 1, newIndex);
        setList(newList);
    }
    // render options 选项卡
    function renderOption() {
        return formList[active]?.options?.map((item, index) => {
            let max = (formList[active]?.options?.length || 1) - 1;
            return (
                <div
                    onDragStart={dragStartFn.bind(this, index)}
                    onDragOver={dragOverFn.bind(this, index)}
                    onDragEnd={dragEndFn.bind(this)}
                    draggable
                    key={index}
                    className="config-item-option"
                >
                    <input
                        onChange={changeOptionValue.bind(this, index)}
                        value={item.label}
                        type="text"
                    />
                    <div className="config-item-option-edit">
                        <ArrowUpOutlined
                            className={`config-item-option-disa${
                                index === 0 ? "bled" : ""
                            }`}
                            onClick={orderOptionFn.bind(
                                this,
                                index,
                                false,
                                index === 0
                            )}
                        />
                        <ArrowDownOutlined
                            className={`config-item-option-disa${
                                index === max ? "bled" : ""
                            }`}
                            onClick={orderOptionFn.bind(
                                this,
                                index,
                                true,
                                index === max
                            )}
                        />
                    </div>
                    <DeleteOutlined
                        onClick={delOptionFn.bind(this, index)}
                        className="config-item-option-del"
                    />
                </div>
            );
        });
    }
    return (
        <div className="config">
            <If show={active !== -1}>
                <>
                    {/* 标签 */}
                    <div className="config-item">
                        <p className="config-item-title">标签</p>
                        <div>
                            <Input
                                allowClear={true}
                                onChange={changeValue.bind(this, "label")}
                                placeholder="请输入"
                                value={formList[active]?.label}
                            />
                        </div>
                    </div>
                    {/* 是否必填 */}
                    <div className="config-item">
                        <p className="config-item-title">是否必填</p>
                        <div>
                            <Switch
                                onChange={changeValue.bind(this, "required")}
                                checked={formList[active]?.required}
                            />
                        </div>
                    </div>
                    {/* 禁用控件 */}
                    <div className="config-item">
                        <p className="config-item-title">禁用控件</p>
                        <div>
                            <Switch
                                onChange={changeValue.bind(this, "disabled")}
                                checked={formList[active]?.disabled}
                            />
                        </div>
                    </div>
                    {/* 此刻/今天 */}
                    <If show={formList[active]?.showToday !== undefined}>
                        <div className="config-item">
                            <p className="config-item-title">此刻/今天</p>
                            <div>
                                <Switch
                                    onChange={changeValue.bind(
                                        this,
                                        "showToday"
                                    )}
                                    checked={formList[active]?.showToday}
                                />
                            </div>
                        </div>
                    </If>
                    {/* 提示语 */}
                    <div className="config-item">
                        <p className="config-item-title">提示语</p>
                        <div>
                            <Input
                                allowClear={true}
                                onChange={changeValue.bind(this, "tips")}
                                placeholder="请输入"
                                value={formList[active]?.tips}
                            />
                        </div>
                    </div>
                    {/* rule */}
                    <div className="config-item">
                        <p className="config-item-title">限制规则</p>
                        <div>
                            <Select
                                showSearch
                                onChange={changeValue.bind(this, "rule")}
                                placeholder="请选择"
                                allowClear={true}
                                value={formList[active]?.rule}
                                filterOption={(input, option) =>
                                    (
                                        option!.children as unknown as string
                                    ).includes(input)
                                }
                            >
                                {OptionsValidate.map((its) => {
                                    return (
                                        <Option
                                            key={its.value}
                                            value={its.value}
                                        >
                                            {its.label}
                                        </Option>
                                    );
                                })}
                            </Select>
                        </div>
                    </div>
                    {/* options */}
                    <If show={formList[active]?.options !== undefined}>
                        <div className="config-item">
                            <p className="config-item-title">选项</p>
                            <div>{renderOption()}</div>
                            <Button
                                type="primary"
                                onClick={addOptionFn.bind(this)}
                            >
                                新增
                            </Button>
                        </div>
                    </If>

                    <Button onClick={delItemFn.bind(this)} type="primary">
                        删除
                    </Button>
                </>
            </If>
        </div>
    );
};
export default Config;
